package edu.polsl.bio.str.frontend.client.dotplot;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Image;
import com.reveregroup.gwt.imagepreloader.ImageLoadEvent;
import com.reveregroup.gwt.imagepreloader.ImageLoadHandler;
import com.reveregroup.gwt.imagepreloader.ImagePreloader;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.SelectionType;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Img;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.layout.VLayout;
import edu.polsl.bio.str.frontend.client.constants.Config;

import java.util.LinkedHashMap;

/**
 * //todo class description
 * <p/>
 * Created on: Jul 31, 2011 7:31:13 PM <br/>
 * <a href="http://www.polsl.pl">www.polsl.pl</a>
 *
 * @author lukasz.olczak@polsl.pl
 */
public class DotPlotEntryPoint implements EntryPoint {

  private SelectItem refIndividualItem;

  private SelectItem refChromosomeItem;

  private SelectItem queryIndividualItem;

  private SelectItem queryChromosomeItem;

  private TextItem forwardFactorItem;

  private TextItem backwardFactorItem;

  private VLayout imgPanel;

  private int originalWidth;

  private int originalHeight;

  private Image img;

  private LinkedHashMap<String, String> individualMap;

  private LinkedHashMap<String, String> chromosomeMap;

  private Config config;

  public void onModuleLoad() {
    config = (Config) GWT.create(Config.class);
    initMaps();
    VLayout main = new VLayout();
    main.setWidth100();
    final DynamicForm form = new DynamicForm();
    form.setGroupTitle("Dot plot:");
    form.setWidth(1000);
    form.setNumCols(4);
    form.setColWidths("25%", "25%", "25%", "25%");

    refIndividualItem = new SelectItem();
    refIndividualItem.setName("refIndividual");
    refIndividualItem.setTitle("Reference individual:");
    refIndividualItem.setValueMap(individualMap);

    refChromosomeItem = new SelectItem();
    refChromosomeItem.setName("refChromosome");
    refChromosomeItem.setTitle("Reference chromosome:");
    refChromosomeItem.setValueMap(chromosomeMap);

    queryIndividualItem = new SelectItem();
    queryIndividualItem.setName("queryIndividual");
    queryIndividualItem.setTitle("Query individual:");
    queryIndividualItem.setValueMap(individualMap);

    queryChromosomeItem = new SelectItem();
    queryChromosomeItem.setName("queryChromosome");
    queryChromosomeItem.setTitle("Query chromosome:");
    queryChromosomeItem.setValueMap(chromosomeMap);

    forwardFactorItem = new TextItem();
    forwardFactorItem.setName("fFactor");
    forwardFactorItem.setTitle("+ correction");

    backwardFactorItem = new TextItem();
    backwardFactorItem.setName("bFactor");
    backwardFactorItem.setTitle("- correction");

    form.setItems(refIndividualItem, refChromosomeItem, queryIndividualItem, queryChromosomeItem, forwardFactorItem, backwardFactorItem);
    main.addMember(form);
    Button downloadButton = new Button();
    downloadButton.setTitle("Download");
    downloadButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent clickEvent) {
        loadImg();
      }
    });
    downloadButton.setAlign(Alignment.CENTER);
    main.addMember(downloadButton);

    final Button fitButton = new Button();
    fitButton.setActionType(SelectionType.CHECKBOX);
    fitButton.setTitle("Fit");
    fitButton.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent clickEvent) {
        imgPanel.removeMembers(imgPanel.getMembers());
        imgPanel.redraw();
        if (fitButton.isSelected()) {
          img.setWidth("1000");
          int height = 1000 * originalHeight / originalWidth;
          img.setHeight(String.valueOf(height));
        } else {
          img.setWidth(String.valueOf(originalWidth));
          img.setHeight(String.valueOf(originalHeight));
        }
        imgPanel.addMember(img);
        imgPanel.redraw();
      }
    });
    fitButton.setAlign(Alignment.CENTER);
    main.addMember(fitButton);

    imgPanel = new VLayout();
    imgPanel.setWidth(1015);
    imgPanel.setHeight(1015);
    imgPanel.setOverflow(Overflow.AUTO);
    imgPanel.setShowEdges(true);
    main.addMember(imgPanel);
    main.setDefaultLayoutAlign(Alignment.CENTER);
    main.draw();
  }

  private void loadImg() {
    final Window winModal = showLoadingWindow();
    ImagePreloader.load(getImageUrl(), new ImageLoadHandler() {
      public void imageLoaded(ImageLoadEvent imageLoadEvent) {
        try {
          imgPanel.removeMembers(imgPanel.getMembers());
          imgPanel.redraw();
          img = imageLoadEvent.takeImage();
          originalWidth = imageLoadEvent.getDimensions().getWidth();
          originalHeight = imageLoadEvent.getDimensions().getHeight();
          img.setWidth(String.valueOf(originalWidth));
          img.setHeight(String.valueOf(originalHeight));
          img.setVisible(true);
          imgPanel.addMember(img);
          imgPanel.redraw();
        } catch (Exception e) {
          com.google.gwt.user.client.Window.alert("Uncaught exception escaped : " + e.getClass().getName() + "\n" + e.getMessage());
        } finally {
          winModal.hide();
        }
      }
    });
  }

  private Window showLoadingWindow() {
    final Window winModal = new Window();
    winModal.setWidth(240);
    winModal.setHeight(70);
    winModal.setTitle("Loading...");
    winModal.setShowMinimizeButton(false);
    winModal.setShowCloseButton(false);
    winModal.setIsModal(true);
    winModal.setShowModalMask(true);
    winModal.centerInPage();

    VLayout panel = new VLayout();
    panel.setAlign(Alignment.CENTER);
    panel.setAlign(VerticalAlignment.CENTER);
    Img img = new Img("loading11.gif");
    img.setAlign(Alignment.CENTER);
    img.setWidth(220);
    img.setHeight(19);
    panel.addMember(img);

    winModal.addItem(panel);
    winModal.show();
    return winModal;
  }

  private String getImageUrl() {
    String url = "http://" +
                 config.dotPlotHost() +
                 ":" +
                 config.dotPlotPort() +
                 "/str-manager/dotplot?refId=" + refIndividualItem.getValue() +
                 "&refChromosomeId=" + refChromosomeItem.getValue() +
                 "&queryId=" + queryIndividualItem.getValue() +
                 "&queryChromosomeId=" + queryChromosomeItem.getValue() +
                 "&width=" +
                 "2000" +
                 "&action=get&factor=" + forwardFactorItem.getValue() +
                 "&bFactor=" + backwardFactorItem.getValue();
    GWT.log(url);
    return url;
  }

  private void initMaps() {
    individualMap = new LinkedHashMap();
    individualMap.put("1", "Human");
    individualMap.put("2", "Neanderthal");
    individualMap.put("3", "Chimp");

    chromosomeMap = new LinkedHashMap();
    chromosomeMap.put("1", "chr1");
    chromosomeMap.put("2", "chr2");
    chromosomeMap.put("3", "chr3");
    chromosomeMap.put("4", "chr4");
    chromosomeMap.put("5", "chr5");
    chromosomeMap.put("6", "chr6");
    chromosomeMap.put("7", "chr7");
    chromosomeMap.put("8", "chr8");
    chromosomeMap.put("9", "chr9");
    chromosomeMap.put("10", "chr10");
    chromosomeMap.put("11", "chr11");
    chromosomeMap.put("12", "chr12");
    chromosomeMap.put("13", "chr13");
    chromosomeMap.put("14", "chr14");
    chromosomeMap.put("15", "chr15");
    chromosomeMap.put("16", "chr16");
    chromosomeMap.put("17", "chr17");
    chromosomeMap.put("18", "chr18");
    chromosomeMap.put("19", "chr19");
    chromosomeMap.put("20", "chr20");
    chromosomeMap.put("21", "chr21");
    chromosomeMap.put("22", "chr22");
    chromosomeMap.put("23", "chrX");
    chromosomeMap.put("24", "chrY");
    chromosomeMap.put("25", "chr2a");
    chromosomeMap.put("26", "chr2b");
  }
}
